import {
    _decorator,
    Component,
    EventTouch,
    game,
    Node,
    view,
    AudioSource,
} from 'cc';
import { request } from './utils/request'
import { Main } from './Main';
import { Logger } from './utils/log';
import { FrameType, ROLE_TYPE } from './enum/frame';
import { RootStore } from 'db://assets/scripts/mixin'
import { ResourceManager, resourceManager } from './ResourceManager';
import { ComponentManager, componentManager } from './ComponentManager';
const { ccclass, property } = _decorator;

@ccclass('GameManager')
export class GameManager extends Component {

    store: RootStore = RootStore.instance

    @property({
        tooltip: 'ResourceManager:资源寄存器',
        displayName: '资源寄存器',
        type: ResourceManager,
    })
    resourceManager = resourceManager;

    @property({
        type: Node,
        tooltip: '触摸节点',
        displayName: '触摸节点',
    })
    touchNode: Node;

    @property({
        type: Main,
        tooltip: 'Main:主容器',
        displayName: '主容器'
    })
    main: Main = null

    @property({
        tooltip: 'ComponentManager:组件管理',
        displayName: '组件管理',
        type: ComponentManager,
    })
    componentManager: ComponentManager = componentManager;

    audioSource: AudioSource

    touchable = false
    ended = false
    #log = new Logger(`主进程${this.name}`)

    start() {
        this.ended = false
        this.webInit()
        game.frameRate = 60
        this.#log.debug("*初始化* start() =>")
    }

    onLoad() {
        this.setNodeActive(true)
        const designResolution = view.getDesignResolutionSize()
        this.#log.debug("*加载完成*", designResolution)
        this.audioSource = this.node.getComponent(AudioSource)
    }

    setNodeActive(active: boolean) {
        if(this.touchable == active) return
        this.touchable = active
        if(active) {
            this.touchNode.on(Node.EventType.TOUCH_START, this.onTouchStart, this)
        } else {
            this.touchNode.off(Node.EventType.TOUCH_START, this.onTouchStart, this)
        }
    }

    onTouchStart(event: EventTouch) {
        const target = event.target as Node
        this.#log.debug('*用户点击* =>', target?.name)
        // this.resourceManager.audioSource.playOneShot(this.resourceManager.globalClickClip)
        this.audioSource.playOneShot(this.resourceManager.globalClickClip)

        if(this.ended) {
            this.#log.debug('*章节结束*')
        } else {
            this.stepNext()
        }
    }

    onTouchEnd() {

    }


    async webInit() {
        const { status, data } = await request.post<LDAPI.Response<LDChapter.ChapterResponse>>(`api/v1/book/preview`).json()
        if(status == 200) {
            this.#log.debug('预览章节数据:', data)
            if(data.dataJson.frames.structure.length) {
                this.store.chapter = data.dataJson
                this.store.currentFrameId = data.dataJson.frames.structure[0].id
            }
            this.run()
        }
    }

    run() {
        this.#log.debug('*开始章节* run() =>', this.store)
        this.frameInit(this.store.currentFrame)

    }

    stepNext() {
        if(this.store.currentFrame.nextId) {
            this.store.currentFrameId = this.store.currentFrame.nextId;
            this.#log.debug('*进入下一帧* stepNext() =>', this.store.currentFrame)
            this.frameInit(this.store.currentFrame)
        } else {
            this.ended = true
            this.#log.debug('*最后一帧*')
        }

    }

    frameInit(frame: LDChapter.Frame) {
        this.#log.debug("*帧初始化* frameInit() =>", frame)
        if(frame.content.type in this.frameMap) {
            this.frameMap[frame.content.type](frame)
        }
    }

    /**
     * 处理对话帧的逻辑。
     * 该函数负责初始化并显示对话帧的内容，包括角色头像、对话文本和对话框样式。
     *
     * @param content - 对话帧的内容，包含角色信息、对话文本和对话框样式。
     *
     * @remarks
     * 该函数首先从资源管理器中获取角色头像资源，然后加载并设置对话框的样式和内容。
     * 最后，它会触发对话框的显示动画，并将当前帧标记为对话帧。
     */
    handleDialogFrame(content: LDContent.DialogContent) {
        this.#log.debug('*对话帧* DialogFrame =>', this.store.currentFrame, content)

        if(content.dialog.who.type in this.dialogMap) {
            this.dialogMap[content.dialog.who.type](content)
        }
    }

    handleBGPFrame(content: LDContent.BGPContent) {
        this.#log.debug('*背景帧* BGPFrame =>', this.store.currentFrame, content)
        this.main.showBGP(content)
    }


    frameMap = {
        [FrameType.BGP]: (frame: LDChapter.Frame) => this.handleBGPFrame(frame.content as LDContent.BGPContent),
        [FrameType.TEXT]: (frame: LDChapter.Frame) => this.handleDialogFrame(frame.content as LDContent.DialogContent),
    }

    dialogMap = {
        [ROLE_TYPE.MAJOR]: (content: LDContent.DialogContent) => this.componentManager.startMajor(content),
        [ROLE_TYPE.MINOR]: (content: LDContent.DialogContent) => this.componentManager.startMinor(content),
        [ROLE_TYPE.NARRATOR]: (content: LDContent.DialogContent) => this.componentManager.startNarator(content),
    }
}


